﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LinqToLfsWorld.Interface;
using System.Runtime.Serialization.Json;
using System.IO;

namespace LinqToLfsWorld.Serialization
{
	/// <summary>
	/// Serializes and deserializes the object to / from a JSON string
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class JsonSerializer<T> : ISerializer<T>
		where T : class
	{

		/// <summary>
		/// Gets the serializer.
		/// </summary>
		/// <value>The serializer.</value>
		protected DataContractJsonSerializer Serializer
		{
			get
			{
				if (_Serializer == null)
					_Serializer = new DataContractJsonSerializer(typeof(T), SerializationTypes.KnownTypes);
				return _Serializer;
			}
		}
		private DataContractJsonSerializer _Serializer = null;


		#region ISerializer<T> Members

		/// <summary>
		/// Serializes the specified object graph.
		/// </summary>
		/// <param name="objectGraph">The object graph.</param>
		/// <returns></returns>
		public string Serialize(T objectGraph)
		{
			string output = null;

			using (MemoryStream ms = new MemoryStream())
			{
				Serializer.WriteObject(ms, objectGraph);
				output = ASCIIEncoding.UTF8.GetString(ms.ToArray());
			}

			return output;
		}

		/// <summary>
		/// Deserializes the specified serialized object graph.
		/// </summary>
		/// <param name="serialized">The serialized object graph.</param>
		/// <returns></returns>
		public T Deserialize(string serialized)
		{
			StringReader reader = new StringReader(serialized);
			T outputObject = default(T);

			using (MemoryStream ms = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(serialized)))
			{
				outputObject = Serializer.ReadObject(ms) as T;
			}

			return outputObject;
		}

		#endregion
	}
}
